# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from ..nuonuo_api.odoo_nuonuo import OdooNuonuo
from ..nuonuo_api.nuonuo import access_token


# from .crypt_util import aes_encrypt, test_aes_enc_dec

from ..nuonuo_print.crypt_nuonuo import print_encrypt

import datetime

import logging

_logger = logging.getLogger(__name__)


ONE_HOUR = 3600


def access_token_check(company_config_id):
    config = company_config_id
    last = config.lasttime
    expires_in = config.expires_in
    now = datetime.datetime.now()
    token = config.access_token

    if token and last and expires_in:
        if (now - last).total_seconds() < (expires_in - ONE_HOUR):
            return

    refresh_token = config.refresh_token
    user_id = config.user_id
    app_secret = config.app_secret

    res = access_token(refresh_token, user_id, app_secret)

    return res


def nuonuo_get(fapiao_draw):
    company = fapiao_draw.company_id

    company_nuonuo = company.env['fp.company.nuonuo'].search(
        [('company_id', '=', company.id)], limit=1)

    company_nuonuo.access_token_check()
    req_url = fapiao_draw.draw_provider_id.endpoint

    appkey = company_nuonuo.appkey
    app_secret = company_nuonuo.app_secret
    token = company_nuonuo.access_token
    tin = company_nuonuo.tin

    # _logger.info(' fapiao...req_url:%s,', req_url)
    # _logger.info(' fapiao...appkey:%s,', appkey)
    # _logger.info(' fapiao...app_secret:%s,', app_secret)
    # _logger.info(' fapiao...token:%s,', token)
    # _logger.info(' fapiao...tin:%s,', tin)
    # _logger.info(' fapiao...values:%s,', values)

    nuonuo = OdooNuonuo(req_url, appkey, app_secret, token, tin)
    return nuonuo


def create_fapiao(fapiao_draw):
    # print('12345678890', 'create_fapiao', self)

    result = []
    for one in fapiao_draw:
        # time.sleep(10)
        serial_num = _api_create_fapiao(one)

        result.append({
            'id': one.id,
            'serial_num': serial_num})

    # print('12345678890', 'create_fapiao', result)

    return result


def _api_create_fapiao(fapiao_draw):

    # _logger.info('  fapiao...')

    fapiao = fapiao_draw.fapiao_id

    fields = [
        # 'name',
        # 'date_order',
        'type',
        'invoice_type',

        'buyer_name',
        'buyer_tin',
        'buyer_phone',
        'buyer_address',
        'buyer_bank_account',

        'saler_tin',
        'saler_phone',
        'saler_address',
        'saler_bank_account',

        'note',
    ]

    values_list = fapiao.read(fields)

    values = values_list[0]
    # _logger.info('  fapiao...values:%s,', values)

    del values['id']

    values['taxmachine_code'] = fapiao_draw.taxmachine_code
    values['checker_name'] = fapiao_draw.checker_name
    values['payee_name'] = fapiao_draw.payee_name
    values['drawer_name'] = fapiao_draw.drawer_name
    values['order_num'] = fapiao.name
    values['date_order'] = fapiao.date_order.strftime('%Y-%m-%d %H:%M:%S')
    values['line_ids'] = [{
        'line_num': str(line.id),
        'vat_product_code':  line.vat_product_code,
        'product_name':  line.product_name,
        'product_spec':  line.product_spec,
        'product_uom':  line.product_uom,
        'quantity':  line.quantity,
        'price_tax_selection':  "tax_included",
        'price_unit':  line.price_unit,
        "tax_ratio": line.tax_ratio / 100,
        "amount_tax": line.amount_tax,
        "amount_untaxed": line.amount_untaxed,
        "amount_total": line.amount_total,
        # "invoiceLineProperty" ?

    }for line in fapiao.line_ids]

    nuonuo = nuonuo_get(fapiao_draw)
    response = nuonuo.create(values)
    # _logger.info('  fapiao...response:%s,', response)

    _logger.info("Nuonuo call to request fapiao by: %s" % values)

    error = response.get('error')
    if error:
        # print('error', response)
        raise ValueError("create fapiao error for %s: %r" % (fapiao, response))

    serial_num = response.get('result')
    if not serial_num:
        # print('error', response)
        raise ValueError("create fapiao error for %s: %r" % (fapiao, response))

    return serial_num


def read_fapiao(fapiao_draw):
    fapiao = fapiao_draw

    fapiao_serial_num_list = fapiao.mapped('nuonuo_serial_num')
    todo = fapiao_serial_num_list[0:50]
    result = _api_read_fapiao(fapiao, todo)

    result2 = []

    for one in result:
        rec = fapiao.filtered(
            lambda r: r.nuonuo_serial_num == one['serial_num'])
        one['id'] = rec.id
        result2.append(one)

    return result2


def _api_read_fapiao(fapiao, serial_num_list):
    # print('_api_read_fapiao', self, serial_num_list)
    # 必须是同一家公司的 发票
    nuonuo = nuonuo_get(fapiao[0])

    response = nuonuo.read(serial_num_list)
    error = response.get('error')
    if error:
        # print('error', response)
        # return
        raise ValueError("read fapiao error for %s: %r" % (fapiao, response))

    result = response.get('result')
    if not result:
        # print('error', response)
        # return
        raise ValueError("read fapiao error for %s: %r" % (fapiao, response))

    return result


def invalid_fapiao(fapiao_draw):
    # _logger.info(' fapiao.invalid_fapiao:%s,', fapiao_draw)
    fapiao = fapiao_draw

    result = []

    for fp in fapiao:
        one = _api_invalid_fapiao(fp)
        if one:
            result.append({
                'id': fp.id,
                'nuonuo_serial_num': one
            })

    return result


def _api_invalid_fapiao(fapiao_draw):
    fapiao = fapiao_draw
    fapiao_serial_num = fapiao.nuonuo_serial_num
    fapiao_code = fapiao.fapiao_id.type_code
    fapiao_num = fapiao.fapiao_id.code

    nuonuo = nuonuo_get(fapiao)
    response = nuonuo.invalid(fapiao_serial_num, fapiao_code, fapiao_num)
    error = response.get('error')
    if error:
        _logger.info('fapiao invalid_fapiao error:%s,', response)
        return
        # raise ValueError("invalid fapiao error for %s: %r" %
        #                  (fapiao, response))

    result = response.get('result')
    if not result:
        _logger.info('fapiao invalid_fapiao error:%s,', response)
        return
        # raise ValueError("invalid fapiao error for %s: %r" %
        #                  (fapiao, response))

    return result


def print_batch_fapiao(fapiao_draw):
    fapiao = fapiao_draw

    # fapiao_serial_num = fapiao.nuonuo_serial_num
    # fapiao_code = fapiao.fapiao_id.type_code
    # fapiao_num = fapiao.fapiao_id.code

    company = fapiao[0].company_id
    company_nuonuo = company.env['fp.company.nuonuo'].search(
        [('company_id', '=', company.id)], limit=1)

    tin = company_nuonuo.tin

    # print_type = fapiao_draw._context.get('print_type')
    # # print_type = 0: 发票打印，1: 清单打印，2: 批量打印，3: 清单批量打印

    nuonuo = nuonuo_get(fapiao[0])

    data = []
    for fpd in fapiao_draw:
        one = fpd.fapiao_id
        fp_code = one.type_code
        fp_num = one.code
        fp_amount = one.amount_total

        data.append({
            'money': fp_amount,
            'taxNum': tin,
            'invoiceCode': fp_code,
            'invoiceNum': fp_num,
        })

    response = nuonuo.print_batch(data)

    res = {
        'ids': fapiao_draw.ids,
        'result': response['result']
    }

    return res


def print_fapiao(fapiao_draw):

    draw_provider_id = fapiao_draw[0].draw_provider_id
    api_provider_id = draw_provider_id.api_provider_id

    print('print_fapiao,fapiao_draw', fapiao_draw)

    company = fapiao_draw[0].company_id
    company_nuonuo = company.env['fp.company.nuonuo'].search(
        [('company_id', '=', company.id)], limit=1)

    tin = company_nuonuo.tin
    print_rsa_pub_key = api_provider_id.print_rsa_pub_key
    print_aes_key = company_nuonuo.print_aes_key
    # print_aes_key = 'OrUPI3VOgAvLtyxA'

    # print_type = fapiao_draw._context.get('print_type')
    print_type = '0'
    # print_type = 0: 发票打印，1: 清单打印，2: 批量打印，3: 清单批量打印

    # print('print_fapiao,print_rsa_pub_key', print_rsa_pub_key)

    result = []
    for one_draw in fapiao_draw:
        one = one_draw.fapiao_id
        fp_code = one.type_code
        fp_num = one.code
        fp_amount = one.amount_total

        res = print_encrypt(tin, print_rsa_pub_key, print_aes_key,
                            print_type, fp_code, fp_num, fp_amount)

        print('print_fapiao ok', res)
        result.append({
            'id': one_draw.id,
            'encryptdata': res
        })

    return result
